// CSE571 - client-interpreter.h
// Authors: Jonathan Wald, Guangle Fan        
// Defines the client interpreter, a subclass of the
// abstract interpreter.  


#include <string>
#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>

#include "ace/Synch.h"

#include "abstract-interpreter.h"
#include "client-interpreter.h"
#include "async-io-svc-handler.h"
#include "game-manager.h"
#include "player-svc-handler.h"
#include "player-game.h"

using namespace std;

// This is the only thread that mutates list of player games so no
// synchronization is necessary.
void ClientInterpreter::define(string filename) {
  if (filename.empty()) {
    std::cout << "No filename given, not (re)initializing." << std::endl;
    return;
  }
  GameManager* manager =  GameManager::instance();
  ACE_Guard<ACE_Thread_Mutex> guard(manager->games_lock);
  for (unsigned int i = 0; i < manager->games.size(); ++i) {
    manager->games[i]->terminated = true;
  }
  // Pointers are lost but memory is not leaked.  Games will delete themselves
  // after their current game
  manager->games.clear();

  char* cstr;
  cstr = new char[filename.size() + 1];
  strcpy(cstr, filename.c_str());
  manager->init(1, &cstr);

}

void ClientInterpreter::current(string label, string value) {
  // If label is empty, then call info on the entire client service, otherwise
  // find the specific game service and call info on that.
  GameManager* manager =  GameManager::instance();
  if(label.empty()) {
    manager->info(NULL);
    return;
  } else if (value.empty()) {
    for (unsigned int i = 0; i < manager->games.size(); ++i) {
      if (manager->games[i]->label == label) {
	manager->games[i]->info(NULL);
	return;
      }
    }
    std::cout << "Label does not identify a service." << std::endl;
    return;
  } else {
    for (unsigned int i = 0; i < manager->games.size(); ++i) {
      if (manager->games[i]->label == label) {
	manager->games[i]->label = value;
	return;
      }
    }
    std::cout << "Label does not identify a service." << std::endl;
    return;
  }
}

void ClientInterpreter::play(string game_type) {
  GameManager* manager = GameManager::instance();
  if (game_type == "draw") {
    manager->plays_draw = true;
  } else if (game_type == "holdem") {
    manager->plays_holdem = true;
  } else if (game_type == "stud") {
    manager->plays_stud = true;
  }
}

void ClientInterpreter::dontplay(string game_type) {
  GameManager* manager = GameManager::instance();
  if (game_type == "draw") {
    manager->plays_draw = false;
  } else if (game_type == "holdem") {
    manager->plays_holdem = false;
  } else if (game_type == "stud") {
    manager->plays_stud = false;
  }
}

void ClientInterpreter::suspend(string game) {
  GameManager* manager = GameManager::instance();
  if(game.empty()) {
    manager->suspend();
    return;
  }
  for (unsigned int i = 0; i < manager->games.size(); ++i) {
    if (manager->games[i]->game_name == game) {
      manager->games[i]->suspend();
      return;
    }
  }
  std::cout << "No game with that name exists." << std::endl;
  return;
}

void ClientInterpreter::resume(string game) {
  GameManager* manager = GameManager::instance();
  if(game.empty()) {
    manager->resume();
    return;
  }
  for (unsigned int i = 0; i < manager->games.size(); ++i) {
    if (manager->games[i]->game_name == game) {
      manager->games[i]->resume();
      return;
    }
  }
  std::cout << "No game with that name exists." << std::endl;
  return;
}
